package org.example.impl;

import org.example.DAO.UContentDao;
import org.example.entity.SearchResult;
import org.example.entity.UContent;
import org.example.entity.Comment;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

public class UContentDaoImpl implements UContentDao {
    private final DataSource dataSource;

    public UContentDaoImpl(DataSource dataSource) {
        this.dataSource = dataSource;
    }



    @Override
    public List<SearchResult> searchContent(String sql, String query, String type, int limit, int offset) throws SQLException {
        List<SearchResult> results = new ArrayList<>();
        try (Connection conn = dataSource.getConnection();
             PreparedStatement pstmt = conn.prepareStatement(sql)) {

            String searchPattern = "%" + query + "%";
            pstmt.setString(1, searchPattern);
            pstmt.setString(2, searchPattern);
            pstmt.setString(3, searchPattern);

            int paramIndex = 4;
            if (!"all".equals(type)) {
                pstmt.setString(paramIndex++, type);
            }

            pstmt.setInt(paramIndex++, limit);
            pstmt.setInt(paramIndex, offset);

            try (ResultSet rs = pstmt.executeQuery()) {
                while (rs.next()) {
                    SearchResult result = new SearchResult();
                    result.setId(rs.getString("id"));
                    result.setType(rs.getString("type"));
                    result.setTitle(rs.getString("title"));
                    result.setAuthor(rs.getString("author"));
                    result.setYear(rs.getString("year"));
                    result.setDescription(rs.getString("description"));
                    result.setImageUrl(rs.getString("image_url"));
                    result.setRating(rs.getFloat("rating"));
                    result.setReviewCount(rs.getInt("rating_count"));
                    results.add(result);
                }
            }
        }
        return results;
    }

    @Override
    public int getSearchCount(String sql, String query, String type) throws SQLException {
        try (Connection conn = dataSource.getConnection();
             PreparedStatement pstmt = conn.prepareStatement(sql)) {

            String searchPattern = "%" + query + "%";
            pstmt.setString(1, searchPattern);
            pstmt.setString(2, searchPattern);
            pstmt.setString(3, searchPattern);

            if (!"all".equals(type)) {
                pstmt.setString(4, type);
            }

            try (ResultSet rs = pstmt.executeQuery()) {
                if (rs.next()) {
                    return rs.getInt(1);
                }
                return 0;
            }
        }
    }



    @Override
    public List<UContent> getPopularContents(int limit) throws SQLException {
        String sql = "SELECT * FROM contents ORDER BY rating DESC, review_count DESC LIMIT ?";
        return getContentsWithLimit(sql, limit);
    }

    @Override
    public List<UContent> getNewestContents(int limit) throws SQLException {
        String sql = "SELECT * FROM contents ORDER BY created_at DESC LIMIT ?";
        return getContentsWithLimit(sql, limit);
    }

    @Override
    public boolean updateContentRating(int contentId, double newRating, int ratingCount) throws SQLException {
        String sql = "UPDATE contents SET rating = ?, rating_count = ? WHERE id = ?";
        try (Connection conn = dataSource.getConnection();
             PreparedStatement pstmt = conn.prepareStatement(sql)) {

            pstmt.setDouble(1, newRating);
            pstmt.setInt(2, ratingCount);
            pstmt.setInt(3, contentId);

            return pstmt.executeUpdate() > 0;
        }
    }
    @Override
    public UContent getContentById(int id) throws SQLException {
        String sql = "SELECT * FROM contents WHERE id = ?";
        try (Connection conn = dataSource.getConnection();
             PreparedStatement pstmt = conn.prepareStatement(sql)) {

            pstmt.setInt(1, id);

            try (ResultSet rs = pstmt.executeQuery()) {
                if (rs.next()) {
                    return mapRowToUContent(rs);
                }
                return null;
            }
        }
    }
    private UContent mapRowToUContent(ResultSet rs) throws SQLException {
        UContent content = new UContent();
        content.setId(rs.getInt("id"));
        content.setTitle(rs.getString("title"));
        content.setType(rs.getString("type"));
        content.setImageUrl(rs.getString("image_url"));
        content.setDescription(rs.getString("description"));
        content.setGenre(rs.getString("genre"));
        content.setRating(rs.getDouble("rating"));
        content.setRatingCount(rs.getInt("rating_count"));

        switch(content.getType()) {
            case "movie":
                content.setDirectorOrAuthor(rs.getString("director"));
                content.setReleaseOrPublishDate(rs.getString("release_year"));
                content.setDurationOrPages(rs.getString("duration"));
                content.setCastOrPublisher(rs.getString("cast"));
                break;
            case "book":
                content.setDirectorOrAuthor(rs.getString("author"));
                content.setReleaseOrPublishDate(rs.getString("publish_year"));
                content.setDurationOrPages(rs.getString("pages"));
                content.setCastOrPublisher(rs.getString("publisher"));
                break;
            case "music":
                content.setDirectorOrAuthor(rs.getString("artist"));
                content.setReleaseOrPublishDate(rs.getString("release_year"));
                content.setDurationOrPages(rs.getString("duration"));
                content.setCastOrPublisher(rs.getString("album"));
                break;
        }

        return content;
    }
    @Override
    public List<UContent> getRecommendations(String contentType, int excludeId, int limit) throws SQLException {
        String sql = "SELECT * FROM contents WHERE type = ? AND id != ? " +
                "ORDER BY rating DESC, review_count DESC LIMIT ?";

        List<UContent> recommendations = new ArrayList<>();
        try (Connection conn = dataSource.getConnection();
             PreparedStatement pstmt = conn.prepareStatement(sql)) {

            pstmt.setString(1, contentType);
            pstmt.setInt(2, excludeId);
            pstmt.setInt(3, limit);

            try (ResultSet rs = pstmt.executeQuery()) {
                while (rs.next()) {
                    recommendations.add(mapUContent(rs));
                }
            }
        }
        return recommendations;
    }

    @Override
    public List<Comment> getComments(int contentId) throws SQLException {
        List<Comment> comments = new ArrayList<>();
        String sql = "SELECT * FROM comments WHERE content_id = ?";
        try (Connection conn = dataSource.getConnection();
             PreparedStatement pstmt = conn.prepareStatement(sql)) {

            pstmt.setInt(1, contentId);
            try (ResultSet rs = pstmt.executeQuery()) {
                while (rs.next()) {
                    Comment comment = new Comment();
                    comment.setId(rs.getInt("id"));
                  //  comment.setAuthor(rs.getString("author"));
                  //  comment.setDate(rs.getString("date"));
                   // comment.setContent(rs.getString("content"));
                    comments.add(comment);
                }
            }
        }
        return comments;
    }

    private List<UContent> getContentsWithLimit(String sql, int limit) throws SQLException {
        List<UContent> contents = new ArrayList<>();
        try (Connection conn = dataSource.getConnection();
             PreparedStatement pstmt = conn.prepareStatement(sql)) {

            pstmt.setInt(1, limit);
            try (ResultSet rs = pstmt.executeQuery()) {
                while (rs.next()) {
                    contents.add(mapUContent(rs));
                }
            }
        }
        return contents;
    }

    private UContent mapUContent(ResultSet rs) throws SQLException {
        UContent content = new UContent();
        content.setId(rs.getInt("id"));
        content.setTitle(rs.getString("title"));
        content.setType(rs.getString("type"));
        content.setImageUrl(rs.getString("image_url"));
        content.setDescription(rs.getString("description"));
        content.setDirectorOrAuthor(rs.getString("director"));
        content.setReleaseOrPublishDate(rs.getString("release_year"));
        content.setGenre(rs.getString("genre"));
        content.setDurationOrPages(rs.getString("duration"));
        content.setCastOrPublisher(rs.getString("cast"));
        content.setRating(rs.getDouble("rating"));
        content.setRatingCount(rs.getInt("rating_count"));
        content.setCreatedAt(rs.getTimestamp("created_at"));
        content.setUpdatedAt(rs.getTimestamp("updated_at"));
        return content;
    }
}